/*******************************************************************************
 * Copyright:   Copyright (c) 2007. Hisilicon Technologies, CO., LTD. 
 * Version:     V300R001B04  
 * Filename:    sequencer.c
 * Description:   This C source code manages the actions to execute under target
 * History:
     1.Created by Huang Yonghua on 2007/12/15
*******************************************************************************/
//#include "syslib.h"
#include <windows.h>
#include "sequencer.h"
#include "download.h"
#include "hisi6810_gpio.h"
//#include "hisi6810_gpio_reg.h"
#include "Uartdrv.h"
#include "ipl_disp_common.h"

RECT   g_stRect;
BOOL   g_dwSdUpdateFlag = FALSE;
WCHAR  aTmpStr[10] = {0};

#define BLOCK_SIZE     16384
#define DISCONNECT_TIME     100

/* output */
#define MPE_WAKE_MPE    GPIO_18   /* AP:DTR - > CP:DSR */
#define MPE_READY_AP    GPIO_19   /* ?? RST ind  AP (I)*/
#define MPE_RST         GPIO_20
#define MPE_POWER_ON    GPIO_21

/* input */
#define MPE_WAKE_AP     GPIO_22   /* AP:DSR < - CP:DTR */
#define MPE_READY_MPE   GPIO_23
#define MPE_VINT        GPIO_24
#define MPE_MON1        GPIO_25
#define MPE_MON2        GPIO_26
#define MPE_TRIG_IN     GPIO_27

#define MPE_DTR         MPE_WAKE_MPE
#define MPE_DSR         MPE_WAKE_AP
#define MPE_RESET_IND   MPE_READY_AP
#define MPE_RESERVED    MPE_READY_MPE

#define MPE_PRESENT     MPE_VINT


#define MPE_RST_GPIO    GPIO_20
#define MPE_PWR_GPIO    GPIO_21
#define MPE_VINT_GPIO   GPIO_24


#define MOD_RESET_CTRL          GPIO_0_0 // active low
#define MOD_PWR_CTRL            GPIO_0_1 // active low
#define DTE_UART_STATE          GPIO_0_2 // active low

#define COUNT_MSEC              184000  // cpu cycle count msec


/*
 * STATIC VARIABLES
 *****************************************************************************/

/*
 * GLOBAL VARIABLES
 *****************************************************************************/

SequencerContext sequencerContext;
SequencerContext* pSequencerContext=&sequencerContext;

#define  pTargetConfig     (pSequencerContext->m_ptTargetConfig)

#define pt_HandleComConfig    (pSequencerContext->m_ptHandleComConfig)

DWORD g_TotalLen;



/*
 * FUNCTIONS
 *****************************************************************************/
BFLOADER_COM_ERROR_CODE_T  ut_ModemReset(BOOL bPrset);
BFLOADER_COM_ERROR_CODE_T  ut_ModemPowerup(BOOL bPwrup);
static BFLOADER_COM_ERROR_CODE_T   BR_InitializeDialog();
static BFLOADER_COM_ERROR_CODE_T   BR_ExecuteCode( unsigned int un_BaseAddress, int n_Delay );
static BFLOADER_COM_ERROR_CODE_T   BR_GetMemorydevice( unsigned int un_BaseAddress, int *pn_MemoryDeviceType );
static BFLOADER_COM_ERROR_CODE_T   BR_DownloadData( unsigned int un_BaseAddress, unsigned int un_DataLength, unsigned char *puc_Data, BOOL b_ChipsetIsSecure,   const  unsigned int *pun_SignOffset);

static BFLOADER_COM_ERROR_CODE_T   LD_InitializeDialog();
static BFLOADER_COM_ERROR_CODE_T   LD_GetMemoryDevice( unsigned int un_BaseAddress,  int *pn_MemoryDeviceType );
static BFLOADER_COM_ERROR_CODE_T   LD_EraseFlash( const MemoryDevice *pt_MemoryDevice, const EraseConfig *pt_EraseConfig, unsigned int un_AppLength );
static BFLOADER_COM_ERROR_CODE_T   LD_DownloadData(unsigned int un_BaseAddress, unsigned int un_DataLength, unsigned char *puc_Data, BOOL b_ChipsetIsSecure,const  unsigned int *pun_SignOffset );

static BFLOADER_COM_ERROR_CODE_T   LD_ExecuteCode( unsigned int un_BaseAddress, int n_Delay );
static BFLOADER_COM_ERROR_CODE_T   LD_FlashLastData( void);

extern void Delay(UINT32 count);

#if 0
#if !defined (WM_DEBUG_EN)
static void Sleep(unsigned long ms)
{
#define COUNTER 0x1ff

    unsigned long i=0;

    for(i=0; i<COUNTER; i++)
        ;

}
#endif
#endif


/****************************************************************************
 *
 * Function:     SendMessageToMMI()
 *
 * Description:     Send a Message to the MMI 
 *
 * Input parameters:  n_CmdId    Command identifier
 *     s_Msg    Message
 *     
 * Output parameters:     void
 *
 * Return:     TRUE or FALSE
 *
 *****************************************************************************/

#if !defined (WM_DEBUG_EN)
static int   SendMessageToMMI( int n_CmdId, char* s_Msg )
{
    n_CmdId=n_CmdId;
    s_Msg=s_Msg;
    //tSendMessageToMMI(n_CmdId,s_Msg);

    return 1;
}

static  int   ManageError( int n_ErrorId,const  char* s_Msg )
{
#if  (1==0)
    char     sErrorMsg[128];

    // Additional error msg
    if ( pSequencerContext->m_nErrorId != n_ErrorId )
    {
        switch (n_ErrorId)
        {
        case COMERR_UARTCREATEFILE:

            strcpy(sErrorMsg , "Selected COM device not currently available");
            SendMessageToMMI(BFLOADERAPP_THREADTOMMI_ERROR, sErrorMsg);
            break;

        case COMERR_CHECKSUMERROR:

            strcpy(sErrorMsg ,"Check sum error");
            SendMessageToMMI(BFLOADERAPP_THREADTOMMI_ERROR, sErrorMsg);
            break;

        case COMERR_RXTIMEOUT:

            strcpy(sErrorMsg , "Reception timeout");
            SendMessageToMMI(BFLOADERAPP_THREADTOMMI_ERROR, sErrorMsg);
            break;

        case COMERR_RXUNCOMPLETE:

            strcpy(sErrorMsg ,"Reception uncomplete");
            SendMessageToMMI(BFLOADERAPP_THREADTOMMI_ERROR, sErrorMsg);
            break;

        case COMERR_CREQNOTRECEIVE:

            strcpy(sErrorMsg ,"Connection request error: Check target settings");
            SendMessageToMMI(BFLOADERAPP_THREADTOMMI_ERROR, sErrorMsg);
            break;

        case COMERR_CACKNOTRECEIVE:

            strcpy(sErrorMsg , "Command not acknowledged");
            SendMessageToMMI(BFLOADERAPP_THREADTOMMI_ERROR, sErrorMsg);
            break;
        case COMERR_BADSIGNATURE:

            strcpy(sErrorMsg ,"Connection request error: 'E' characters received");
            SendMessageToMMI(BFLOADERAPP_THREADTOMMI_ERROR, sErrorMsg);
            strcpy(sErrorMsg , "Check application signature and customer id are valid ");
            SendMessageToMMI(BFLOADERAPP_THREADTOMMI_ERROR, sErrorMsg);
            break;

        default:
            break;
        }
    }

    // Update error Id
    pSequencerContext->m_nErrorId = n_ErrorId;

    // Main error
    //sErrorMsg.Format( "Err %03d\t - %s", n_ErrorId, s_Msg );
    SendMessageToMMI(BFLOADERAPP_THREADTOMMI_ERROR, sErrorMsg);

    return n_ErrorId;
#else

    return 1;
#endif

}
#endif

/****************************************************************************
 *
 * Function:     ConvertWordToBuffer()
 *
 * Description:     Convert a word into a buffer of byte 
 *
 * Input parameters:     n_word    word to convert
 *     
 * Output parameters:     pc_buffer result buffer
 *
 * Return:     void
 *
 *****************************************************************************/

static  void   ConvertWordToBuffer(unsigned  int n_word, unsigned char *pc_buffer )
{
    // Convert buffer
    pc_buffer[3] = (n_word >> 24) & 0xFF;
    pc_buffer[2] = (n_word >> 16) & 0xFF;
    pc_buffer[1] = (n_word >>    8) & 0xFF;
    pc_buffer[0] = (n_word     ) & 0xFF;
}
/****************************************************************************
 *
 * Function:     ConvertBufferToWord()
 *
 * Description:     Convert a buffer of byte into a word 
 *
 * Input parameters:     pc_buffer     Buffer to convert
 *     
 * Output parameters:     pn_word    Result word
 *
 * Return:     void
 *
 *****************************************************************************/
static  void  ConvertBufferToWord( const unsigned char *pc_buffer, unsigned int *pn_word )
{
    *pn_word  = (pc_buffer[3] & 0xff) << 24;
    *pn_word |= (pc_buffer[2] & 0xff) << 16;
    *pn_word |= (pc_buffer[1] & 0xff) <<  8;
    *pn_word |= (pc_buffer[0] & 0xff);
}

/*****************************************************************************
 *
 * Function:     IsSophiaExternalLoader()
 *
 * Description:     return TRUE if OTP is used to set a chip in secure mode
 *
 * Input parameters:    none
 *
 * Output parameters:    void
 *
 * Return:     TRUE for sophia external loader     
 *
 *****************************************************************************/
BOOL IsSophiaExternalLoader( )
{
#if (0==1)
    if ( ( m_sLoaderFile.Find( CString( "emirload.bin" ) ) != -1 )
            || ( m_sLoaderFile.Find( CString( "jucaload.bin" ) ) != -1 )
            || ( m_sLoaderFile.Find( CString( "wukongload.bin" ) ) != -1 ) )
    {
        return TRUE;
    }
    else
    {
        return FALSE;
    }
#endif

    return FALSE;
}

/*****************************************************************************
 *
 * Function:     SEQ_SetSequencerParam()
 *
 * Description:     Set the sequencer parameters
 *
 * Input parameters:    pt_TargetConfig
 *
 * Output parameters:    void
 *
 * Return:     TRUE or FALSE
 *
 *****************************************************************************/

BOOL SEQ_SetSequencerParam( TargetConfig *pt_TargetConfig )
{
    if ( pt_TargetConfig == NULL )
    {
        return FALSE;
    }
    // Update sequencer parameters
    pTargetConfig= pt_TargetConfig;

    return TRUE;
}

/*
 * PRIVATE FUNCTIONS
 *****************************************************************************/

/*****************************************************************************
 *
 * Function:     SEQ_InitSeq()
 *
 * Description:     Sequencer initialization
 *
 * Input parameters:    void
 *
 * Output parameters:    void
 *
 * Return:     int
 *
 *****************************************************************************/
BFLOADER_COM_ERROR_CODE_T SEQ_InitSeq(void)
{
    //int     targetId;
    //unsigned int     unCmd;
    BFLOADER_COM_ERROR_CODE_T     nResult = ERR_NOERROR;

    // Init Dialog, MMI message is moved in SEQ_MainSeq()
#if defined (WM_DEBUG_EN)
    //OALMSG(1,(TEXT(" Waiting for board reset...\r \r\n")));
#else
    SendMessageToMMI( BFLOADERAPP_THREADTOMMI_INFO, "Waiting for board reset..." );
#endif

    // PARSE CMD and reject bad command process
    // ----------------------------------------------
    //  unCmd =m_ptTargetConfig->GetScenario()->GetCommandType();
    //unCmd =(unsigned int)  pSequencerContext->targetConfig.m_tScenario.m_nCommandType;//
    pt_HandleComConfig = &pTargetConfig->m_atLinkConfig[DFLT_BR_COMCONFIG].m_tComConfig;
    if ( ( nResult = BFLOADER_ComConfigInitDialog( pTargetConfig->m_nTargetId,
                     pt_HandleComConfig,
                     NULL) ) != ERR_NOERROR )
    {
        // Error during Communication initialization
#if defined (WM_DEBUG_EN)
        DEBUGMSG(1,(TEXT(" Error during Communication initialization  nResult=%d\r\n"),nResult));
#else

        ManageError( nResult, "Error during Communication initialization" );
#endif

        return nResult;
    }

    pSequencerContext->m_bCmdTarget = CMD_BOOTROM;
	
	ut_ModemPowerup(TRUE);
	
	// Initialize communication with Boot ROM
	if ( ( nResult = BR_InitializeDialog() ) != ERR_NOERROR  )
	{
			// Error in Initialize Boot ROM dialog
#if defined (WM_DEBUG_EN)
			DEBUGMSG(1,(TEXT(" Error in Initialize Boot ROM dialog	nResult=%d\r\n"),nResult));
#else
	
			ManageError( nResult, "Error in Initialize Boot ROM dialog" );
#endif
	
			return nResult;
	}
#if defined (WM_DEBUG_EN)
	else
	{
		DEBUGMSG(1,(TEXT(" Boot rom initialization complete\r\n")));
	}
#endif

   
    return ERR_NOERROR;
}


/*****************************************************************************
 *
 * Function:     SEQ_CloseSeq()
 *
 * Description:     Sequencer closure
 *
 * Input parameters:    void
 *
 * Output parameters:    void
 *
 * Return:     int
 *
 *****************************************************************************/

BFLOADER_COM_ERROR_CODE_T   SEQ_CloseSeq(void )
{
    return  BFLOADER_ComCloseDialog(NULL);
}

/*****************************************************************************
 *
 * Function:     SEQ_MainSeq()
 *
 * Description:     Main sequencer function
 *
 * Input parameters:    void
 *
 * Output parameters:    void
 *
 * Return:     int
 *
 *****************************************************************************/

BFLOADER_COM_ERROR_CODE_T   SEQ_MainSeq_ERASE(void)
{
    int     nMemoryDeviceType;
    unsigned int  unCurBaseAdd = 0;
    unsigned int  unSCRAMBaseAdd = 0;
    unsigned int  unSignOffset = 0;
    BFLOADER_COM_ERROR_CODE_T    nResult;
 
    //  targetId = pTargetConfig->m_nTargetId;
    if( pTargetConfig->m_bLoaderIsExternal== TRUE )
    {
        if (pSequencerContext->m_pucLoaderData == NULL)
        {
            // Error in Read file
#if defined (WM_DEBUG_EN)
            DEBUGMSG(1,(TEXT(" Error in Read Loader Data\r\n")));
#else
            ManageError( ERR_ERROR, "Error in Read Loader Data" );
#endif

            SendDataToPC(APP_ERR_ERROR);
            return ERR_ERROR;
        }
    }
    else
    {
#if defined (WM_DEBUG_EN)
    	DEBUGMSG(1,(TEXT(" Please Select The Loader File. \r\n"))); 
#endif

        SendDataToPC(APP_ERR_ERROR);
        return ERR_ERROR;

    }

    // Update Device Address with current memory device address
    unCurBaseAdd =pTargetConfig->m_atMemoryDevice[pTargetConfig->m_nCurMemDevice].m_unBaseAddress;

    // Update Device Address with SCRAM address if internal loader
    if ( pTargetConfig->m_bLoaderIsExternal== TRUE )
    {
        unSCRAMBaseAdd = pTargetConfig->m_atMemoryDevice[pTargetConfig->m_nLoaderMemDevice].m_unBaseAddress;
        //m_bSophiaExternalLoader =IsSophiaExternalLoader();
    }
    else
    {
        unSCRAMBaseAdd = pTargetConfig->m_atMemoryDevice[SCRAM_MEMDEVICE].m_unBaseAddress;
    }

    // Update Jump delay
    //nJumpDelay = pTargetConfig->m_tScenario.m_unJumpDelay;
    if ( ( ( pTargetConfig->m_tScenario.m_nCommandType& BFLOADERAPP_CMD_WRITE ) == BFLOADERAPP_CMD_WRITE )
            || ( ( pTargetConfig->m_tScenario.m_nCommandType& BFLOADERAPP_CMD_ERASE ) == BFLOADERAPP_CMD_ERASE ) )

    {
        nMemoryDeviceType=-1;
        if ( ( nResult = BR_GetMemorydevice( unCurBaseAdd, &nMemoryDeviceType  ) ) != ERR_NOERROR  )
        {
            // Error during get memory device
#if defined (WM_DEBUG_EN)
            DEBUGMSG(1,(TEXT(" Error during get memory device  nResut=%d\r\n"),nResult));
#else

            ManageError( nResult, "Error during get memory device" );
#endif

            return nResult;
        }
#if defined (WM_DEBUG_EN)
        else
        {
            DEBUGMSG(1,(TEXT(" BR. Get memory device OK. nMemoryDeviceType=%d\r\n"),nMemoryDeviceType));
        }
#endif

        /*
        If memory type is RAM download application in RAM
        Else Download Loader in RAM
        --------------------------------------------------------------
        */
        pSequencerContext->m_nMemoryDeviceType = nMemoryDeviceType;
        switch ( nMemoryDeviceType )
        {
        case MEMDEVICE_RAM : // Memory Device is RAM
            break;

        case MEMDEVICE_FLASH : // Memory Device is FLASH
            /*
            Memory type is FLASH or NAND_FLASH: download loader in RAM
            run loader, erase Flash memory and write application in Flash
            --------------------------------------------------------------
            */
            // Download loader in SCRAM
            // Update MMI
#if defined (WM_DEBUG_EN)

            DEBUGMSG(1,(TEXT("Data len=0x%x,Downloading loader  in SCRAM start... \r\n"),pSequencerContext->m_nLoaderDataLength));
#else

            SendMessageToMMI( BFLOADERAPP_THREADTOMMI_INFO, "Downloading loader  in SCRAM" );
#endif


            if ( ( nResult = BR_DownloadData(    unSCRAMBaseAdd,
                                                 (unsigned int)pSequencerContext->m_nLoaderDataLength,
                                                 pSequencerContext->m_pucLoaderData,
                                                 FALSE,
                                                 &unSignOffset ) ) != ERR_NOERROR  )
            {
                // Error during download loader in SCRAM
#if defined (WM_DEBUG_EN)
                DEBUGMSG(1,(TEXT("Error during download loader in SCRAM\r\n"),nResult));
#else

                ManageError( nResult, "Error during download loader in SCRAM" );
#endif

                return nResult;
            }
            else
            {
                // Update MMI
#if defined (WM_DEBUG_EN)
                DEBUGMSG(1,(TEXT("Loader downloaded in SCRAM OK.\r\n")));
#else

                SendMessageToMMI( BFLOADERAPP_THREADTOMMI_INFO, "Loader downloaded in SCRAM" );
#endif

            }

            // Execute Loader code
            if ( ( nResult = BR_ExecuteCode( unSCRAMBaseAdd, 0 ) ) != ERR_NOERROR  )
            {
                // Error during execute command
#if defined (WM_DEBUG_EN)
                DEBUGMSG(1,(TEXT("Error during execute Loader Code command\r\n")));
#endif

                SendDataToPC(APP_ERR_ERROR);
                return ERR_ERROR;

            }

            pSequencerContext->m_bCmdTarget = CMD_LOADER;

            // Initialize communication with Loader
            if ( ( nResult = LD_InitializeDialog() ) != ERR_NOERROR  )
            {
                // Error during loader initialization
#if defined (WM_DEBUG_EN)
                DEBUGMSG(1,(TEXT("Error during loader initialization  nResult=%d\r\n"),nResult));
#else

                ManageError( nResult, "Error during loader initialization" );
#endif

                return nResult;
            }


            // Get memory device
            nMemoryDeviceType=-1;
            if ( ( nResult = LD_GetMemoryDevice( unCurBaseAdd, &nMemoryDeviceType  ) ) != ERR_NOERROR  )
            {
                // Error during get memory device
#if defined (WM_DEBUG_EN)
                DEBUGMSG(1,(TEXT("Error during get app. memory device  nResult=%d\r\n"),nResult));
#else

                ManageError( nResult, "Error during get memory device" );
#endif

                return nResult;
            }
#if defined (WM_DEBUG_EN)
            else
            {
                // DEBUGMSG(1,(TEXT("LD_GetMemoryDevice Done. nMemoryDeviceType=%d,unCurBaseAdd=0x%x\r\n"),nMemoryDeviceType,unCurBaseAdd));
            }
#endif

            // Update memory type
            pSequencerContext->m_nMemoryDeviceType = nMemoryDeviceType;

            DEBUGMSG(1,(TEXT("The CommandType is :[%x] \%*************** \r\n"),(pTargetConfig->m_tScenario.m_nCommandType)));

			// Check Command ERASE
            // -------------------
            if ( (pTargetConfig->m_tScenario.m_nCommandType & BFLOADERAPP_CMD_ERASE ) == BFLOADERAPP_CMD_ERASE )
            {
               //  SendDataToPC(0x8f);
               //  DEBUGMSG(1,(TEXT("**************Send the erase flag :[%x] \%*************** \r\n"),0x8f));

                // Erase FLASH device
                if ( ( nResult = LD_EraseFlash( &pTargetConfig->m_atMemoryDevice[pTargetConfig->m_nCurMemDevice],
                                                &pTargetConfig->m_tScenario.m_tEraseConfig,
                                                (unsigned int)pSequencerContext->m_nAppliDataLength ) ) != ERR_NOERROR  )
                {
                    // Error during flash erase
#if defined (WM_DEBUG_EN)
                    DEBUGMSG(1,(TEXT("Error during flash erase  nResult=%d\r\n"),nResult));
#else
                    ManageError( nResult, "Error during flash erase" );
#endif

                    return nResult;
                }
    
            }

            break;
	    
        default:

			break;
        } // end switch
    }  //end BFLOADERAPP_CMD_WRITE || BFLOADERAPP_CMD_ERASE
    return ERR_NOERROR;
}


/*****************************************************************************
*
* Function:     SEQ_MainSeq_BH()
*
* Description:     Main sequencer function
*
* Input parameters:    void
*
* Output parameters:    void
*
* Return:     int
*
*****************************************************************************/

BFLOADER_COM_ERROR_CODE_T   SEQ_MainSeq_BH(void)
{
    unsigned int unCurBaseAdd = 0;
    unsigned int unSignOffset = 0;
    BFLOADER_COM_ERROR_CODE_T nResult;

    // Update Device Address with current memory device address

    unCurBaseAdd = pTargetConfig->m_atMemoryDevice[pTargetConfig->m_nCurMemDevice].m_unBaseAddress;

    g_TotalLen =  pSequencerContext->m_nAppliDataLength;
  

    // Update Jump delay
    //nJumpDelay = pTargetConfig->m_tScenario.m_unJumpDelay;
    if (((pTargetConfig->m_tScenario.m_nCommandType & BFLOADERAPP_CMD_WRITE) == BFLOADERAPP_CMD_WRITE)
        || ((pTargetConfig->m_tScenario.m_nCommandType & BFLOADERAPP_CMD_ERASE) == BFLOADERAPP_CMD_ERASE))

    {
        /*
         Memory type is FLASH or NAND_FLASH: download loader in RAM
         run loader, erase Flash memory and write application in Flash
         --------------------------------------------------------------
         */

        if (((pTargetConfig->m_tScenario.m_nCommandType & BFLOADERAPP_CMD_ERASE) == BFLOADERAPP_CMD_ERASE)
            && (ERR_NOERROR == ComMgr_GetEraseMsg()))
        {
            // Update MMI
#if defined (WM_DEBUG_EN)
            DEBUGMSG(1, (TEXT("Flash erased Done.\r\n")));
#else
            SendMessageToMMI( BFLOADERAPP_THREADTOMMI_INFO, "Flash erased" );
#endif
        }
        else
        {
#if defined (WM_DEBUG_EN)
            DEBUGMSG(1, (TEXT("Error during flash erase!\r\n")));
#else
            SendMessageToMMI( BFLOADERAPP_THREADTOMMI_INFO, "Error during flash erase!" );
#endif

            return ERR_ERROR;
        }

        // Check command WRITE
        // -------------------
        if ((pTargetConfig->m_tScenario.m_nCommandType & BFLOADERAPP_CMD_WRITE) == BFLOADERAPP_CMD_WRITE)
        {
            // Download application in FLASH
            if ((nResult = LD_DownloadData(    unCurBaseAdd,
                                               (unsigned int) pSequencerContext->m_nAppliDataLength,
                                               pSequencerContext->m_pucAppliData,
                                               FALSE /*  pSequencerContext->m_bChipsetIsSecure*/,
                                               &unSignOffset)) != ERR_NOERROR)
            {
                // Error during download application in Flash
#if defined (WM_DEBUG_EN)
                DEBUGMSG(1, (TEXT("Error during download application in Flash  nResult=%d\r\n"), nResult));
#else
                ManageError( nResult, "Error during download application in Flash" );
#endif

                return nResult;
            }
        }      // End command Write
    }  //end BFLOADERAPP_CMD_WRITE || BFLOADERAPP_CMD_ERASE

    return ERR_NOERROR;
}


/*****************************************************************************
 *
 * Function:     ut_ModemReset()
 *
 * Description:     Modem power up
 *
 * Input parameters: BOOL bPwrup TRUE: power up, else modem power down
 *
 * Output parameters:    BFLOADER_COM_ERROR_CODE_T
 *
 * Return:     int
 *
 *****************************************************************************/
BFLOADER_COM_ERROR_CODE_T  ut_ModemReset(BOOL bReset)
{

    if(bReset)
    {

        /* DSR disable*/
        //  GpioSetDirection(GPIO_18,EGPIO_DIR_OUTPUT);
        //  GpioSetValue(GPIO_18, EGPIO_DATA_HIGH);

        /* RST */
        GpioSetDirection(MOD_RESET_CTRL, EGPIO_DIR_OUTPUT);
        GpioSetValue(MOD_RESET_CTRL, EGPIO_DATA_HIGH);

        /* DSR enable*/
        // GpioSetDirection(GPIO_18,EGPIO_DIR_OUTPUT);
        //GpioSetValue(GPIO_18, EGPIO_DATA_LOW);
    }


    return ERR_NOERROR;
}


/*****************************************************************************
 *
 * Function:     ut_ModemPowerup()
 *
 * Description:     Modem power up
 *
 * Input parameters: BOOL bPwrup TRUE: power up, else modem power down
 *
 * Output parameters:    BFLOADER_COM_ERROR_CODE_T
 *
 * Return:     int
 *
 *****************************************************************************/

BFLOADER_COM_ERROR_CODE_T   ut_ModemPowerup(BOOL bPwrup)
{
    if(bPwrup)
    {
        // EdbgOutputDebugString("++Modem Start Power On.....\r\n");
        // DEBUGMSG(1,(TEXT("ut_ModemPowerup ++\r\n")));
        //reset GPIO direction & value
        GpioSetDirection(MOD_RESET_CTRL, EGPIO_DIR_OUTPUT); // output pin
        GpioSetDirection(MOD_PWR_CTRL, EGPIO_DIR_OUTPUT);	 // output pin
        GpioSetDirection(DTE_UART_STATE, EGPIO_DIR_OUTPUT); // output pin

        //Set DTE_UART_STATE = Inactive
        GpioSetValue(DTE_UART_STATE, EGPIO_DATA_HIGH);

        //Set MOD_RESET_CTRL = Active
        GpioSetValue(MOD_RESET_CTRL, EGPIO_DATA_LOW);

        // simulate press on ON_KEY
        GpioSetValue(MOD_PWR_CTRL, EGPIO_DATA_HIGH);

        Delay(200);

        GpioSetValue(MOD_PWR_CTRL, EGPIO_DATA_LOW);

        //Set MOD_RESET_CTRL = Inactive
        GpioSetValue(MOD_RESET_CTRL, EGPIO_DATA_HIGH);

        //DEBUGMSG(1,(TEXT("ut_ModemPowerup --\r\n")));
        // EdbgOutputDebugString("--Modem Start Power Finished.....\r\n");
    }
    else
    {
        GpioSetDirection(MOD_PWR_CTRL, EGPIO_DIR_OUTPUT);
        GpioSetValue(MOD_PWR_CTRL, EGPIO_DATA_HIGH);

        Delay(1500);

        GpioSetValue(MOD_PWR_CTRL, EGPIO_DATA_LOW);
    }

    return ERR_NOERROR;
}



/*****************************************************************************
 *
 * Function:     ut_ExecuteCode()
 *
 * Description:     Execute code at address
 *
 * Input parameters:    n_CmdType     Command to use Boot ROM or Loader
 *     un_BaseAddress  Base address
 *     n_Delay     Execute code after this time in ms
 *     range: 0 to 25.5s step 100 ms
 *
 * Output parameters:    void
 *
 * Return:     int
 *
 *****************************************************************************/

BFLOADER_COM_ERROR_CODE_T   ut_ExecuteCode( int n_CmdType, unsigned int un_BaseAddress, int n_Delay )
{
    BOOL bErr=FALSE;
    int     nTimeout;
    int     nExecuteCmdSize=0;
    unsigned char aucCmdData[4];

    BFLOADER_COM_CMD_TYPE_T     nSetAddCmd=CMD_NOCOMMAND;
    BFLOADER_COM_CMD_TYPE_T     nExecuteCmd=CMD_NOCOMMAND;
    BFLOADER_COM_ERROR_CODE_T     nResult;

    // Command depends on target dialer Boot ROM or Loader
    switch ( n_CmdType )
    {
    case CMD_BOOTROM:
        nSetAddCmd = CMD_BR_SETADD;

        // If Delay is null immediate jump
        // Else Execute after delay
        if ( n_Delay == 0 )
        {
            nExecuteCmd     = CMD_BR_JUMP;
            nExecuteCmdSize = 0;
        }
        else
        {
            nExecuteCmd = CMD_BR_EXEC;
            nExecuteCmdSize = 1;
        }
        break;

    case CMD_LOADER:
        nSetAddCmd     = CMD_LD_SETADD;
        nExecuteCmd     = CMD_LD_EXEC;
        nExecuteCmdSize = 1;
        break;

    default:
        //return ERR_ERROR;
        bErr=TRUE;
        break;
    }

    if(bErr)
    {
        SendDataToPC(APP_ERR_ERROR);
        return ERR_ERROR;
    }

    // Set default timeout
    nTimeout = 1000;

    // Set base address
    //  ConvertWordToBuffer( un_BaseAddress, (char *)aucCmdData );
    ConvertWordToBuffer( un_BaseAddress, aucCmdData );
    if (( nResult = BFLOADER_ComSendCmd(NULL,
                                        (int) nSetAddCmd,
                                        4,
                                        aucCmdData,
                                        0,
                                        nTimeout,
                                        NULL,
                                        NULL ) ) != ERR_NOERROR )
    {
        // Error during set address
#if defined (WM_DEBUG_EN)
        DEBUGMSG(1,(TEXT("Error during set address  nResult=%d\r\n"),nResult));
#else

        ManageError( nResult, "Error during set address" );
#endif

        return nResult;
    }

    // Delay translation
    if (  n_Delay < ( 0xFF * 100 ) ) // inf to 25.5 s
    {
        aucCmdData[0] = (unsigned char)n_Delay / 100;
    }
    else
    {
        aucCmdData[0] = 0xFF;
    }

    // Execute command
    if ( ( nResult = BFLOADER_ComSendCmd(NULL,
                                         (int)nExecuteCmd,
                                         nExecuteCmdSize,
                                         aucCmdData,
                                         0,
                                         nTimeout,
                                         NULL,
                                         NULL ) ) != ERR_NOERROR )
    {
        // Error during execute command
#if defined (WM_DEBUG_EN)
        DEBUGMSG(1,(TEXT("Error during execute command nResult=%d\r\n"),nResult));
#else

        ManageError( nResult, "Error during execute command" );
#endif

        return nResult;
    }
    return ERR_NOERROR;
}

/*****************************************************************************
 *
 * Function:     ut_SendData()
 *
 * Description:     Send data to target
 *
 * Input parameters:    n_CmdType     Command to use Boot ROM or Loader
 *     un_BaseAddress  Base address
 *     un_DataLength   Data length in bytes
 *     puc_Data     Data to send
 *
 * Output parameters:    void
 *
 * Return:     int
 *
 *****************************************************************************/
static BFLOADER_COM_ERROR_CODE_T   ut_SendData( int n_CmdType, unsigned int un_BaseAddress,   unsigned int un_DataLength, unsigned char *puc_Data )
{
    BOOL bErr=FALSE;
    int     nTimeout=0;
    unsigned int  unIndex=0;
    unsigned int  unFrameSize=0;
    unsigned char aucCmdData[4];
    DWORD DSendCnt = 0;
    UINT32  UCoeff = 0;
    static UINT8  n = 0;
    UINT8    UpData = 0;

    BFLOADER_COM_ERROR_CODE_T     nResult;
    BFLOADER_COM_CMD_TYPE_T     nLoadCmd=CMD_NOCOMMAND;
    BFLOADER_COM_CMD_TYPE_T     nSetAddCmd=CMD_NOCOMMAND;

    unsigned long sendcnt=0;


    int    Tmpcount = 0;


    // Command depends on target dialer Boot ROM or Loader
    switch ( n_CmdType )
    {
    case CMD_BOOTROM:
        nSetAddCmd = CMD_BR_SETADD;
        nLoadCmd   = CMD_BR_LOAD;
        break;

    case CMD_LOADER:
        nSetAddCmd = CMD_LD_SETADD;
        nLoadCmd   = CMD_LD_LOAD;
        break;

    default:
        bErr=TRUE;
        //return ERR_ERROR;
        break;
    }

    if(bErr)
    {
#if defined (WM_DEBUG_EN)
        DEBUGMSG(1,(TEXT("ut_SendData,n_CmdType  Error nResult\r\n")));
#endif

        SendDataToPC(APP_ERR_ERROR);

        return ERR_ERROR;
    }

    // Calculate timeourt TBM
    nTimeout = 1200;   //1000

    // Set base address
    //  ConvertWordToBuffer( un_BaseAddress, (char *)aucCmdData );
    ConvertWordToBuffer( un_BaseAddress, aucCmdData );

    nResult = ERR_NOERROR;
    if ( ( nResult = BFLOADER_ComSendCmd(NULL,
                                         (int)nSetAddCmd,
                                         4,
                                         aucCmdData,
                                         0,
                                         nTimeout,
                                         NULL,
                                         NULL ) ) != ERR_NOERROR )
    {
        // Error during set address
#if defined (WM_DEBUG_EN)
        DEBUGMSG(1,(TEXT("ut_SendData,Error during set address nResult=%d\r\n"),nResult));
#else

        ManageError( nResult, "Error during set address" );
#endif

        return nResult;
    }

    // Download application in FLASH
    // If un_DataLength < 200 -> one shot
    // Else download by frame
    // MZA SpeedUp change to 0x200(512bytes) one small page
    // 06/04/06 TBM test if Bootrom be abble to download
    // with transfert size > 512 bytes
    if ( n_CmdType ==(int) CMD_LOADER )
    {
        switch (pSequencerContext->m_nMemoryDeviceType )
        {
        case MEMDEVICE_RAM :
            unFrameSize = BFLOADERDLL_RAM_TRANSFERT_SIZE;
            break;

        default :
            {
                unFrameSize = BFLOADERDLL_UART_NOR_FLASH_TRANSFERT_SIZE;
            }
            break;
        }
    }
    else if ( n_CmdType ==(int) CMD_BOOTROM)
    {
        unFrameSize = BFLOADERDLL_RAM_TRANSFERT_SIZE;
    }

    if ( un_DataLength >= unFrameSize )
    {
        //unFrameSize = 0x200;    // PHB => SpeedUp( un_DataLength / 200 ) * 4;
        unIndex = 0;
     
        while ( unIndex < un_DataLength )
        {
            // Update counter
            //unCounter = ( ( 100 * unIndex ) / un_DataLength ) + 1;
            if ( ( unIndex + unFrameSize ) >= un_DataLength )
            {
                // Update frame size
                unFrameSize = un_DataLength - unIndex;
                //unCounter = 100;
            }


            // Load Command
            if ( ( nResult = BFLOADER_ComSendCmd(NULL,
                                                 (int)nLoadCmd,
                                                 (int)unFrameSize,
                                                 &puc_Data[unIndex],
                                                 0,
                                                 nTimeout,
                                                 NULL,
                                                 NULL ) ) != ERR_NOERROR )
            {

#if defined (WM_DEBUG_EN)
                DEBUGMSG(1,(TEXT("ut_SendData, ERR: Err_1: unFrameSize=%d, nResult=%d\r\n"),unFrameSize,nResult));

#endif

                return nResult;
            }
            else
            {
                /*Submit the process data (0x20 + %g_Complete) modified by Scott 2008/3/19*/

                if(CMD_LD_LOAD == nLoadCmd)
                {
	                DSendCnt = DSendCnt + unFrameSize*10;
	                UCoeff = ( g_TotalLen * 10 ) / 98;

	                if(DSendCnt + UCoeff >= (UCoeff *n))
	                {
	                    n++;
	                    UpData = 0x20 + n;
	                    if(g_dwSdUpdateFlag)
				        {
				        	IplSetBarPrec(n);
				
							OALLogPrintf(aTmpStr, 10, L"%3d%%  ", n);
							
							IplDrawFirstLineText(aTmpStr, IplWcslen(aTmpStr), &g_stRect, 0);
				        }
				        else
				        {
				        	SendDataToPC(UpData);
				        }
	                }
               	}

            }

            // Update MMI
            unIndex += unFrameSize;

        }
    }
    else
    {
        // Load command
        if ( ( nResult = BFLOADER_ComSendCmd(NULL,
                                             (int) nLoadCmd,
                                             (int) un_DataLength,
                                             puc_Data,
                                             0,
                                             nTimeout,
                                             NULL,
                                             NULL ) ) != ERR_NOERROR )
        {
            // Error during load command
#if defined (WM_DEBUG_EN)
            DEBUGMSG(1,(TEXT("ut_SendData,BFLOADER_ComSendCmd2  error nResult=%d\r\n"),nResult));
            EdbgOutputDebugString("ut_SendData,BFLOADER_ComSendCmd2  error nResult=%d\r\n",nResult);
#else

            ManageError( nResult, "Error during load command" );
#endif

            return nResult;
        }
    }
    return ERR_NOERROR;
}


/*****************************************************************************
 *
 * Function:     BR_InitializeDialog()
 *
 * Description:     Initialize communication with Boot ROM
 *     Begin dialog with default communication configuration
 *     End dialog user communication configuration
 *     
 * Input parameters:    void
 *
 * Output parameters:    void
 *
 * Return:     int
 *
 *****************************************************************************/
BFLOADER_COM_ERROR_CODE_T
BR_InitializeDialog(void)
{
    int     nTimeout;
    int     nRcvSize;
    unsigned char    aucCmdData[1026]; // TBM
    unsigned char    aucRcvData[1026]; // TBM
    BFLOADER_COM_ERROR_CODE_T     nResult;

#if defined (WM_DEBUG_EN)

    int j;
#endif

    // Set default timeout
    nTimeout = 1000;

    // Wait Board reset
    if ( ( nResult = BFLOADER_ComSendCmd(NULL,
                                         (int) CMD_BR_WAITCON,
                                         0,
                                         NULL,
                                         0,
                                         TIMEOUT_INFINITE,
                                         NULL,
                                         NULL ) ) != ERR_NOERROR )
    {
        // Error in Wait Board reset
#if defined (WM_DEBUG_EN)
        DEBUGMSG(1,(TEXT("Error in Wait Board reset nResult=%d\r\n"),nResult));
        //        EdbgOutputDebugString("Error in Wait Board reset nResult=%d\r\n", nResult);
#endif

        return nResult;
    }

    // Setting target timeout
    aucCmdData[0] = 0xFF; // INFINITE_T
    if ( ( nResult = BFLOADER_ComSendCmd(NULL,
                                         (int) CMD_BR_TIMEOUT,
                                         1, aucCmdData,
                                         0,
                                         nTimeout,
                                         NULL,
                                         NULL ) ) != ERR_NOERROR )
    {
        // Error during command set timeout
#if defined (WM_DEBUG_EN)
        DEBUGMSG(1,(TEXT("Error during set timeout  nResult=%d\r\n"),nResult));
#else

        ManageError( nResult, "Error during set timeout" );
#endif

        return nResult;
    }


    // Send command change communication to user BaudRate Boot ROM config
    aucCmdData[0] =(unsigned char)pTargetConfig->m_atLinkConfig[USER_BR_COMCONFIG].m_tComConfig.tUartConfig.nBaudRate;
    if ( ( nResult = BFLOADER_ComSendCmd(NULL,
                                         (int) CMD_BR_CHANGERATEUART,
                                         1,
                                         aucCmdData,
                                         0,
                                         nTimeout,
                                         aucRcvData,
                                         &nRcvSize) ) != ERR_NOERROR )
    {
        // Error during change baud rate
#if defined (WM_DEBUG_EN)
        DEBUGMSG(1,(TEXT("Error during change baud rate  nResult=%d\r\n"),nResult));
#else

        ManageError( nResult, "Error during change baud rate" );
#endif

        return nResult;
    }

    // Change communication to user Boot ROM config
    pt_HandleComConfig =&(pTargetConfig->m_atLinkConfig[USER_BR_COMCONFIG].m_tComConfig);

    if ( ( nResult = BFLOADER_ComChangeConfig(NULL,
                     pt_HandleComConfig ) ) != ERR_NOERROR )
    {
        // Error during Communication change config
#if defined (WM_DEBUG_EN)
        DEBUGMSG(1,(TEXT("Error during change config  nResult=%d\r\n"),nResult));
#else

        ManageError( nResult, "Error during change config" );
#endif

        return nResult;
    }

    // Read product ID
    if ( ( nResult = BFLOADER_ComSendCmd(NULL,
                                         (int)CMD_BR_READPRODUCTID,
                                         0,
                                         NULL,
                                         5,
                                         nTimeout,
                                         aucRcvData,
                                         &nRcvSize ) ) != ERR_NOERROR )
    {
        // Error during read product ID
#if defined (WM_DEBUG_EN)
        DEBUGMSG(1,(TEXT("Error during read product ID  nResult=%d\r\n"),nResult));
#else

        ManageError( nResult, "Error during read product ID" );
#endif

        return nResult;
    }
#if defined (WM_DEBUG_EN)
    else
    {
        DEBUGMSG(1,(TEXT("Read product ID OK  nRcvSize=%d\r\n"),nRcvSize));
        for (j=0;j<nRcvSize;j++)
        {
            DEBUGMSG(1,(TEXT("product ID ack[%d] = 0x%x\r\r\n"),j,aucRcvData[j]));
        }
    }
#endif
    return ERR_NOERROR;
}
/*****************************************************************************
 *
 * Function:     BR_GetMemorydevice()
 *
 * Description:     Return the memory device type
 *
 * Input parameters:    un_BaseAddress     Base address
 *
 * Output parameters:    pn_MemoryDeviceType Type of memory RAM or FLASH
 *
 * Return:     int
 *
 *****************************************************************************/
BFLOADER_COM_ERROR_CODE_T
BR_GetMemorydevice( unsigned int un_BaseAddress, int *pn_MemoryDeviceType )
{
    int     nTimeout;
    int     nRcvSize;
    unsigned char aucCmdData[1026]; // TBM
    unsigned char aucRcvData[1026]; // TBM
    unsigned int  unWordRead;
    unsigned int  unWordWrite;
    BFLOADER_COM_ERROR_CODE_T     nResult;

    // Set default timeout
    nTimeout = 1000;

    // Set base address
    ConvertWordToBuffer( un_BaseAddress, aucCmdData );
    if ( ( nResult = BFLOADER_ComSendCmd(NULL,
                                         (int)CMD_BR_SETADD,
                                         4,
                                         aucCmdData,
                                         0,
                                         nTimeout,
                                         NULL,
                                         NULL ) ) != ERR_NOERROR )
    {
#if defined (WM_DEBUG_EN)
        DEBUGMSG(1,(TEXT("Error during set CMD_BR_SETADD  address\r\n")));
#endif

        SendDataToPC(APP_ERR_ERROR);

        return ERR_ERROR;
    }

    // Load a random data at base address
#if (0==1)
    srand( (unsigned) time( NULL ) );
    unWordWrite = rand();
#else

    unWordWrite=0x0a0a0a0a;/*add by h00100243*/
#endif

    ConvertWordToBuffer( unWordWrite, aucCmdData );
    if ( ( nResult = BFLOADER_ComSendCmd(NULL,
                                         (int)CMD_BR_LOAD,
                                         4,
                                         aucCmdData,
                                         0,
                                         nTimeout,
                                         NULL,
                                         NULL ) ) != ERR_NOERROR )
    {
        // Error during load data
#if defined (WM_DEBUG_EN)
        DEBUGMSG(1,(TEXT("Error during get memory type nResult=%d\r\n"),nResult));
#else

        ManageError( nResult, "Error during get memory type" );
#endif

        return nResult;
    }

    // Set base address
    // ConvertWordToBuffer( un_BaseAddress, (char *)aucCmdData );
    ConvertWordToBuffer( un_BaseAddress, aucCmdData );
    if ( ( nResult = BFLOADER_ComSendCmd(NULL,
                                         (int)CMD_BR_SETADD,
                                         4,
                                         aucCmdData,
                                         0,
                                         nTimeout,
                                         NULL,
                                         NULL ) ) != ERR_NOERROR )
    {
        // Error during set address
#if defined (WM_DEBUG_EN)
        DEBUGMSG(1,(TEXT("Error during set BR  address  nResult=%d\r\n"),nResult));
#else

        ManageError( nResult, "Error during set address" );
#endif

        return nResult;
    }

    // Get data at base address
    if ( ( nResult = BFLOADER_ComSendCmd(NULL,
                                         (int)CMD_BR_GET,
                                         0,
                                         NULL,
                                         4,
                                         nTimeout,
                                         aucRcvData,
                                         &nRcvSize ) ) != ERR_NOERROR )
    {
        // Error during get data
#if defined (WM_DEBUG_EN)
        DEBUGMSG(1,(TEXT("Error during get data  nResult=%d\r\n"),nResult));
#else

        ManageError( nResult, "Error during get data" );
#endif

        return nResult;
    }

    // Compare data Writen and data Read
    // ConvertBufferToWord( (char *)aucRcvData, (int *)&unWordRead );
    ConvertBufferToWord( (unsigned char *)aucRcvData, (unsigned int *)&unWordRead );

    if ( unWordRead == unWordWrite )
    {
        *pn_MemoryDeviceType = MEMDEVICE_RAM;
    }
    else
    {
        *pn_MemoryDeviceType = MEMDEVICE_FLASH;
    }

    return ERR_NOERROR;
}
/*****************************************************************************
 *
 * Function:     BR_DownloadData()
 *
 * Description:     Download data via boot ROM
 *
 * Input parameters:  un_BaseAddress     Base address
 *     un_DataLength     Data length
 *     puc_Data     Data to download
 *     b_ChipsetIsSecure  True if the chipset is secure
 *     un_SignOffset     Adress to write the signature
 *     
 * Output parameters:    void
 *
 * Return:     int
 *
 *****************************************************************************/
BFLOADER_COM_ERROR_CODE_T  BR_DownloadData( unsigned int un_BaseAddress, unsigned int un_DataLength,
        unsigned char *puc_Data, BOOL b_ChipsetIsSecure, const unsigned int *pun_SignOffset)
{
    BFLOADER_COM_ERROR_CODE_T     nResult;

    // Download data via Boot ROM
    if ( ( nResult = ut_SendData(    CMD_BOOTROM,
                                     un_BaseAddress,
                                     un_DataLength,
                                     puc_Data ) ) != ERR_NOERROR  )
    {
        // Error during download data via Boot ROM
#if defined (WM_DEBUG_EN)
        DEBUGMSG(1,(TEXT("Error during download data via Boot ROM  nResult=%d\r\n"),nResult));
#else

        ManageError( nResult, "Error during download data via Boot ROM" );
#endif

        return nResult;
    }
    return ERR_NOERROR;
}

/*****************************************************************************
 *
 * Function:     BR_ExecuteCode()
 *
 * Description:     Execute code at address after a delay 
 *
 * Input parameters:  un_BaseAddress  Base address
 *     n_Delay     Execute code after this time in ms
 *     
 * Output parameters:    void
 *
 * Return:     int
 *
 *****************************************************************************/
static BFLOADER_COM_ERROR_CODE_T
BR_ExecuteCode( unsigned int un_BaseAddress, int n_Delay )
{
    BFLOADER_COM_ERROR_CODE_T nResult;

    // Download data via Boot ROM
    if ( ( nResult = ut_ExecuteCode(CMD_BOOTROM,
                                    un_BaseAddress,
                                    n_Delay ) ) != ERR_NOERROR  )
    {
        // Error during download data via Boot ROM
#if defined (WM_DEBUG_EN)
        DEBUGMSG(1,(TEXT("Error during BR_ExecuteCode  nResult=%d\r\n"),nResult));
#else

        ManageError( nResult, "Error during BR_ExecuteCode" );
#endif

        return nResult;
    }

    return ERR_NOERROR;
}



/*****************************************************************************
 *
 * Function:     LD_InitializeDialog()
 *
 * Description:     Initialize communication with Loader
 *     Begin dialog with default communication configuration
 *     End dialog user communication configuration
 *
 * Input parameters:    void
 *
 * Output parameters:    void
 *
 * Return:     int
 *
 *****************************************************************************/
BFLOADER_COM_ERROR_CODE_T LD_InitializeDialog(void)
{
    int     nTimeout;
    unsigned char aucCmdData[1026]; // TBM
    unsigned char aucRcvData[1026]; // TBM
    int     nRcvSize = 0;
    BFLOADER_COM_ERROR_CODE_T     nResult;

    // Set default timeout
    nTimeout = 1000;

    // Wait loader init
    // must find and handshake between loader and host
    //Sleep( 1000 );
    Delay( 1000 );

    // Change communication to default Loader config
    pt_HandleComConfig =&pSequencerContext->targetConfig.m_atLinkConfig[DFLT_LD_COMCONFIG].m_tComConfig;
    if ( ( nResult = BFLOADER_ComChangeConfig(NULL,
                     pt_HandleComConfig ) ) != ERR_NOERROR )
    {
        // Error during Communication change config
#if defined (WM_DEBUG_EN)
        DEBUGMSG(1,(TEXT("Error during dcommunication change config  nResult=%d\r\n"),nResult));
#else

        ManageError( nResult, "Error during dcommunication change config" );
#endif

        return nResult;
    }

    // Read Loader version
    nResult = BFLOADER_ComSendCmd(    NULL,
                                      (int)CMD_LD_READLOADERVERSION,
                                      0,
                                      NULL,
                                      5,
                                      nTimeout,
                                      aucRcvData,
                                      &nRcvSize );

    if ( ( nResult == ERR_NOERROR ) ||( nResult == COMERR_RXUNCOMPLETE ) )
    {
#if defined (WM_DEBUG_EN)

        {
            int i;
            DEBUGMSG(1,(TEXT("Loader Version(len=%d): \r\n"),nRcvSize));

            for(i=0;i<nRcvSize;i++)
            {
                DEBUGMSG(1,(TEXT("ver[%d]=0x%x ;\r\n"),i,aucRcvData[i]));
            }
        }
#endif

    }
    else
    {
        // Error during read loader version
#if defined (WM_DEBUG_EN)
        DEBUGMSG(1,(TEXT("Error during read loader version  nResult=%d\r\n"),nResult));
#else

        ManageError( nResult, "Error during read loader version" );
#endif

        return nResult;
    }


    // Send command change communication to user loader config
    aucCmdData[0] =(unsigned char)pSequencerContext->targetConfig.m_atLinkConfig[USER_LD_COMCONFIG].m_tComConfig.tUartConfig.nBaudRate;
    if ( ( nResult = BFLOADER_ComSendCmd(NULL,
                                         (int)CMD_LD_CHANGERATEUART,
                                         1,
                                         aucCmdData,
                                         0,
                                         nTimeout,
                                         aucRcvData,
                                         &nRcvSize) ) != ERR_NOERROR )
    {
        // Error during in change baud rate
#if defined (WM_DEBUG_EN)
        DEBUGMSG(1,(TEXT("Error during change baud rate  nResult=%d\r\n"),nResult));
#else

        ManageError( nResult, "Error during change baud rate" );
#endif

        return nResult;
    }

    // Change communication to user loader config
    pt_HandleComConfig =&pSequencerContext->targetConfig.m_atLinkConfig[USER_LD_COMCONFIG].m_tComConfig;
    if ( ( nResult = BFLOADER_ComChangeConfig(/* &pSequencerContext->m_ulComDevice*/NULL,
                     pt_HandleComConfig ) ) != ERR_NOERROR )
    {
        // Error during Communication change config
#if defined (WM_DEBUG_EN)
        DEBUGMSG(1,(TEXT("Error during change config  nResult=%d\r\n"),nResult));
#else

        ManageError( nResult, "Error during change config" );
#endif

        return nResult;
    }

    return ERR_NOERROR;
}


/*****************************************************************************
 *
 * Function:     LD_EraseFlash()
 *
 * Description:     Erase the FLASH device
 *
 * Input parameters:    pt_MemoryDevice  Current memory device
 *     pt_EraseConfig   Erase configuration
 *     un_AppLength     Application length
 *
 * Output parameters:    void
 *
 * Return:     int
 *
 *****************************************************************************/
BFLOADER_COM_ERROR_CODE_T   LD_EraseFlash( const MemoryDevice *pt_MemoryDevice,	const EraseConfig *pt_EraseConfig, unsigned int un_AppLength )
{
    int     nTimeout;
    int     nEraseTime;
    int     nMinute;
    //int     nSeconde;
    unsigned char aucCmdData[4]; // TBM
    unsigned int    unBaseAdd=0;
    unsigned int    unEraseLength=0;
    int     nBlockSize;
    BOOL bErr=FALSE;
    BFLOADER_COM_ERROR_CODE_T     nResult;

    // Set default timeout
    nTimeout = 1000;

    /* sibley or ST flash 128KWords */
    if ( pSequencerContext->m_bSibleyFlash == TRUE )
    {
        nBlockSize = 128*1024*2;
    }
    else
    {
        nBlockSize = BLOCK_SIZE;
    }

    // Action depends on erase configuration
    //switch ( pt_EraseConfig->GetEraseOption() )
    switch (pt_EraseConfig->m_nEraseOption)
    {
    case ERASE_ALL:

        // Update Base address
        //unBaseAdd = pt_MemoryDevice->GetAddress();
        unBaseAdd = pt_MemoryDevice->m_unBaseAddress;

        // Erase All
        unEraseLength = 0x00;
        break;

    case ERASE_APPLISIZE:

        // Update Base address
        unBaseAdd = pt_MemoryDevice->m_unBaseAddress;

        // Erase application Size
        unEraseLength = un_AppLength;
        break;

    case ERASE_CUSTOM:

        // Update Base address
        unBaseAdd = pt_MemoryDevice->m_unBaseAddress + pt_EraseConfig->m_unEraseOffset;

        // Erase custom Size
        unEraseLength = pt_EraseConfig->m_unEraseLength;

        // Check Erase Size
        if ( ( unEraseLength < un_AppLength )  && ( unEraseLength != 0 ) )
        {
            //strcpy(sMsg,"Custom erase length shorter than Application length");
            //SendMessageToMMI( BFLOADERAPP_THREADTOMMI_WARNING, sMsg );
        }
        break;

    default:
        bErr=TRUE;
        //return ERR_ERROR;
        break;
    }

    if(bErr)
    {
#if defined (WM_DEBUG_EN)
        DEBUGMSG(1,(TEXT("Mem config error in LD_EraseFlash \r\n")));
#endif

        SendDataToPC(APP_ERR_ERROR);

        return ERR_ERROR;
    }
    // Calcul du timeout
    // GetEraseTime in milliseconds
    nEraseTime = (int)pt_MemoryDevice->m_unEraseTime;

    // At least one block to erase
    if ( unEraseLength != 0 )
    {
        nEraseTime = nEraseTime * (int)( unEraseLength / (unsigned )nBlockSize ) +  (int)10000; // Add 10 s. more
    }
    else
    {
        nEraseTime = 300000;
    }

    nMinute    = nEraseTime /60000;
    if ( nMinute != 0 )
    {
        //nSeconde   = ( nEraseTime - ( nMinute * 60000) ) / 1000;
#if (0==1)
        sMsg.Format( "Erasing Flash, you must wait for  %d mn, %d s maximum",
                     nMinute,
                     nSeconde);
#endif

    }
    else
    {
        //nSeconde = nEraseTime / 1000;
        // At least 1 second
        //nSeconde++;
    }

    nTimeout = nEraseTime * 10;
    // Set base address
    ConvertWordToBuffer( unBaseAdd, aucCmdData );
    if ( ( nResult = BFLOADER_ComSendCmd(NULL,
                                         (int)CMD_LD_SETADD,
                                         4,
                                         aucCmdData,
                                         0,
                                         nTimeout,
                                         NULL,
                                         NULL ) ) != ERR_NOERROR )
    {
        // Error during set address
#if defined (WM_DEBUG_EN)
        DEBUGMSG(1,(TEXT("Error during set Erasion address2!  nResult=%d\r\n"),nResult));
#else

        ManageError( nResult, "Error during set address") ;
#endif

        return nResult;
    }

    // Set base address
    ConvertWordToBuffer( unEraseLength, aucCmdData );
    // Erase FLASH memory
#if defined (WM_DEBUG_EN)

    DEBUGMSG(1,(TEXT(",Erase Len=0x%x, Time =%d(minutes) , Erasing...	\r\n"),unEraseLength,nMinute));
#endif

    if ( ( nResult = BFLOADER_ComSendCmd(NULL,
                                         (int)CMD_LD_ERASE,
                                         4,
                                         aucCmdData,
                                         0,
                                         nTimeout,
                                         NULL,
                                         NULL ) ) != ERR_NOERROR )
    {
        // Error during erase address
#if defined (WM_DEBUG_EN)
        DEBUGMSG(1,(TEXT("Error during Flash erase ## nResult=%d\r\n"),nResult));
#else

        ManageError( nResult, "Error during Flash erase" );
#endif

        return nResult;
    }


    return ERR_NOERROR;
}

/*****************************************************************************
 *
 * Function:     LD_GetMemoryDevice()
 *
 * Description:     Get the device memory at adress
 *
 * Input parameters:  un_BaseAddress    Base address
 *     
 * Output parameters:    void
 *
 * Return:     int
 *
 *****************************************************************************/
BFLOADER_COM_ERROR_CODE_T   LD_GetMemoryDevice( unsigned int un_BaseAddress,  int *pn_MemoryDeviceType )
{
    int     nTimeout;
    unsigned char aucCmdData[4]; // TBM
    unsigned char    aucRcvData[40]; // TBM
    int     nRcvSize = 0;
    BFLOADER_COM_ERROR_CODE_T     nResult=ERR_NOERROR;


    // Set default timeout
    nTimeout = 1000;

    // Set base address
    // ConvertWordToBuffer( un_BaseAddress, (char *)aucCmdData );
    ConvertWordToBuffer( un_BaseAddress, aucCmdData );

    if ( ( nResult = BFLOADER_ComSendCmd(NULL,
                                         (int)CMD_LD_SETADD,
                                         4,
                                         aucCmdData,
                                         0,
                                         nTimeout,
                                         NULL,
                                         NULL ) ) != ERR_NOERROR )
    {
        // Error during set address
#if defined (WM_DEBUG_EN)
        DEBUGMSG(1,(TEXT("Error during set address  nResult=%d\r\n"),nResult));
#else

        ManageError( nResult, "Error during set address") ;
#endif

        return nResult;
    }

    // Get memory device
    nResult = BFLOADER_ComSendCmd(NULL,
                                  (int)CMD_LD_GETMEMORYDEVICE,
                                  0,
                                  NULL,
                                  14,/* 32,*/
                                  nTimeout,
                                  aucRcvData,
                                  &nRcvSize );

    if ( ( nResult == ERR_NOERROR ) || ( nResult == COMERR_RXUNCOMPLETE ) )
    {
        switch ( aucRcvData[0] )
        {
        case BFLOADERAPP_MEMORY_RAM:
#if defined (WM_DEBUG_EN)

            DEBUGMSG(1,(TEXT("RAM detected\r\n")));
#else
            //strcpy(sMsg , "RAM detected");
            //SendMessageToMMI( BFLOADERAPP_THREADTOMMI_INFO, sMsg );
#endif

            break;

        case BFLOADERAPP_MEMORY_UNKNOWN:
            //ManageError( ERR_ERROR, "Unknown Flash detected" );
            //return nResult;
            break;

        default:
            if(aucRcvData[0]==BFLOADERAPP_MEMORY_NOR_FLASH)
            {
                *pn_MemoryDeviceType=MEMDEVICE_FLASH;
            }
#if defined (WM_DEBUG_EN)
            DEBUGMSG(1,(TEXT("Nor Flash detected  nRcvSize=%d,aucRcvData[0]=0x%x \r\n"),nRcvSize,aucRcvData[0]));
            {
                int j;
                for (j=0;j<nRcvSize; j++)
                {
                    DEBUGMSG(1,(TEXT("Mem Type Req: ack[%d]=0x%x\r\n"),j, aucRcvData[j]));
                }
            }
            //0x53 0x54 0x5f 0x4d 0x35 0x38 0x57 "ST_M58W"  aucRcvData[0]==0x30
#endif
            break;
        }
    }
    else
    {
        // Error during get memory device
#if defined (WM_DEBUG_EN)
        DEBUGMSG(1,(TEXT("LD_GetMemoryDevice,Error during get memory device type   nResult=%d\r\n"),nResult));
#else

        ManageError( nResult, "Error during get memory device type" );
#endif

        return nResult;
    }
    return nResult;
}


/*****************************************************************************
 *
 * Function:     LD_ExecuteBootROM()
 *
 * Description:     Boot into the boot ROM
 *     
 * Input parameters:    un_Delay    Execute boot after this time in ms
 *     range: 0 to 25.5s step 100 ms
 *     
 * Output parameters:    void
 *
 * Return:     int
 *
 *****************************************************************************/

BFLOADER_COM_ERROR_CODE_T   LD_ExecuteBootROM( unsigned int un_Delay )
{
    int     nTimeout;
    int     nRcvSize;
    unsigned char aucCmdData[16]; // TBM
    unsigned char    aucRcvData[1026]; // TBM
    BFLOADER_COM_ERROR_CODE_T   nResult;

    // Set default timeout
    nTimeout = 1000;

    // Send command change communication to BootRom default BaudRate config
    aucCmdData[0] =(unsigned char)pSequencerContext->targetConfig.m_atLinkConfig[DFLT_BR_COMCONFIG].m_tComConfig.tUartConfig.nBaudRate;
    if ( ( nResult = BFLOADER_ComSendCmd(NULL,
                                         (int)CMD_LD_CHANGERATEUART,
                                         1,
                                         aucCmdData,
                                         0,
                                         nTimeout,
                                         aucRcvData,
                                         &nRcvSize) ) != ERR_NOERROR )
    {
        // Error during in change baud rate
#if defined (WM_DEBUG_EN)
        DEBUGMSG(1,(TEXT("EError during change baud rate  nResult=%d\r\n"),nResult));
#else

        ManageError( nResult, "Error during change baud rate" );
#endif

        return nResult;
    }

    // Change communication to BootRom default BaudRate config
    pt_HandleComConfig =&pSequencerContext->targetConfig.m_atLinkConfig[DFLT_BR_COMCONFIG].m_tComConfig;
    if ( ( nResult = BFLOADER_ComChangeConfig( NULL/*&pSequencerContext->m_ulComDevice*/,
                     pt_HandleComConfig    ) ) != ERR_NOERROR )
    {
        // Error during Communication change config
        //   ManageError( nResult, "Error during change config" );
        return nResult;
    }

    // Delay translation
    if ( un_Delay < ( 0xFF * 100 ) ) // inf to 25.5 s
    {
        aucCmdData[0] =(unsigned char) un_Delay / 100;
    }
    else
    {
        aucCmdData[0] = 0xFF;
    }

    if ( ( nResult = BFLOADER_ComSendCmd(NULL,
                                         (int)  CMD_LD_COLDRESET,
                                         1,
                                         aucCmdData,
                                         0,
                                         nTimeout,
                                         NULL,
                                         NULL ) ) != ERR_NOERROR )
    {
        // Error during cold reset
        return nResult;
    }
    return ERR_NOERROR;
}

/*****************************************************************************
 *
 * Function:     LD_DownloadData
 *
 * Description:     Download data via Loader
 *
 * Input parameters:  un_BaseAddress     Base address
 *     un_DataLength     Data length
 *     puc_Data     Data to download
 *     b_ChipsetIsSecure  True if the chipset is secure
 *     
 * Output parameters: pun_SignOffset     Address to write the signature
 *
 * Return:     int
 *
 *****************************************************************************/
BFLOADER_COM_ERROR_CODE_T   LD_DownloadData(    unsigned int un_BaseAddress, unsigned int un_DataLength,
        unsigned char *puc_Data, BOOL b_ChipsetIsSecure,
        const      unsigned int *pun_SignOffset )
{
    BFLOADER_COM_ERROR_CODE_T     nResult;

    // Download data in 1 part
#if defined (WM_DEBUG_EN)

    DEBUGMSG(1,(TEXT("Downloading application in Flash...\r\n")));
#else

    SendMessageToMMI( BFLOADERAPP_THREADTOMMI_INFO, "Downloading application in Flash..." );
#endif

    if ( ( nResult = ut_SendData(CMD_LOADER, un_BaseAddress, un_DataLength, puc_Data ) ) != ERR_NOERROR  )
    {
        // Error during download application in Flash
#if defined (WM_DEBUG_EN)
        DEBUGMSG(1,(TEXT("LD_DownloadData,Error during SendData...  nResult=%d\r\n"),nResult));
        EdbgOutputDebugString("LD_DownloadData,Error during SendData...  nResult=%d\r\n",nResult );
#else

        ManageError( nResult, "Error during download application in Flash" );
#endif

        return nResult;
    }
    else
    {
        // Update MMI
#if defined (WM_DEBUG_EN)
        DEBUGMSG(1,(TEXT("Modem image data write done\r\n")));
        EdbgOutputDebugString("Modem image data write done\r\n");
#else
		EdbgOutputDebugString("Modem image data write done\r\n");
        SendMessageToMMI( BFLOADERAPP_THREADTOMMI_INFO, "Download done" );
#endif

    }

    //   ut_ModemReset(1);

    if ( (nResult = LD_FlashLastData()) != ERR_NOERROR)
    {
        // Error during download last block in Flash
#if defined (WM_DEBUG_EN)
        DEBUGMSG(1,(TEXT("Error during download application last block in Flash   nResult=%d\r\n"),nResult));
        EdbgOutputDebugString("Error during download application last block in Flash   nResult=%d\r\n", nResult);
#else

        ManageError( nResult, "Error during download application last block in Flash" );
#endif

        return nResult;
    }
    else
    {
        Delay(200);
        
        //Set DTE_UART_STATE = Inactive
        GpioSetValue(DTE_UART_STATE, EGPIO_DATA_LOW);   
        
        GpioSetValue(MOD_PWR_CTRL, EGPIO_DATA_HIGH);
        Delay(1500);
        GpioSetValue(MOD_PWR_CTRL, EGPIO_DATA_LOW);       
        Delay(200);  
        
        if(!g_dwSdUpdateFlag)
        {
        	SendDataToPC(0x20 + 99);
        }

        Delay(1500);
        
        if(g_dwSdUpdateFlag)
        {
        	IplSetBarPrec(100);
				
			OALLogPrintf(aTmpStr, 10, L"%3d%%  ", 100);
			
			IplDrawFirstLineText(aTmpStr, IplWcslen(aTmpStr), &g_stRect, 0);
        }
        else
        {
        	SendDataToPC(0x20 + 100);
        }
        
        EdbgOutputDebugString("download application last block in Flash ok ~~~ \r\n");
    }

    return ERR_NOERROR;
}
/*****************************************************************************
 *
 * Function:     LD_ExecuteCode()
 *
 * Description:     Execute code at address after a delay 
 *
 * Input parameters:    un_BaseAddress  Base address
 *     n_Delay     Execute code after this time in ms
 *     
 * Output parameters:    void
 *
 * Return:     int
 *
 *****************************************************************************/

BFLOADER_COM_ERROR_CODE_T   LD_ExecuteCode( unsigned int un_BaseAddress, int n_Delay )
{
    BFLOADER_COM_ERROR_CODE_T nResult;

    // Download data via Boot ROM
    if ( ( nResult = ut_ExecuteCode( CMD_LOADER, un_BaseAddress, n_Delay ) ) != ERR_NOERROR  )
    {
        // Error during download data via Loader
#if defined (WM_DEBUG_EN)
        DEBUGMSG(1,(TEXT("Error during download data via Loader   nResult=%d\r\n"),nResult));
#else

        ManageError( nResult, "Error during download data via Loader" );
#endif

        return nResult;
    }

    return ERR_NOERROR;
}

/*****************************************************************************
 *
 * Function:     LD_FlashLastData()
 *
 * Description:     Send the command for writing the last data sended in memory
 *
 * Input parameters:     
 *     
 * Output parameters:    
 *
 * Return:     int
 *
 *****************************************************************************/
BFLOADER_COM_ERROR_CODE_T   LD_FlashLastData( void)
{
    int     nTimeout;
    unsigned char aucCmdData[4];
    BFLOADER_COM_ERROR_CODE_T     nResult;

    // DLL_IsSophiaDll();//del by h00100243

    /* m_nSopDLL must be removed when NBG delivered library supporting
    this new comand */
    if (pSequencerContext->m_bSibleyFlash == TRUE  )
    {
        // Set default timeout
        nTimeout = 1000;

        // Update MMI
        //SendMessageToMMI( BFLOADERAPP_THREADTOMMI_INFO, "Download Last Data in Flash" );
        // Send "Flash command" for the last data in the pipe
        nResult = BFLOADER_ComSendCmd( NULL,
                                       (int)CMD_LD_FLASHLASTDATA,
                                       0,
                                       aucCmdData,
                                       0,
                                       nTimeout,
                                       NULL,
                                       NULL );

        if (nResult != ERR_NOERROR)
        {
            // Error during download last block in flash
#if defined (WM_DEBUG_EN)
            DEBUGMSG(1,(TEXT("Error during download last data in Flash   nResult=%d\r\n"),nResult));
            EdbgOutputDebugString("Error during download last data in Flash   nResult=%d\r\n", nResult);
#else

            ManageError( nResult, "Error during download last data in Flash" );
#endif

            return nResult;
        }
    }
    return ERR_NOERROR;
}


/*HISI IF*/
/****************************************************************************
 *
 * Function:     SequencerContextInit()
 *
 * Description:     Initialize the Target memory  context
 *
 * Input parameters:   pMD:     handle to memory device
 *     n_TargetType     target type
 *     n_ConfigId     configuration type
 * Return:     void
 *
 *****************************************************************************/
static void SEQ_MemoryConfigInit( int n_TargetType, int n_ConfigId,MemoryDevice* pMD)
{
    // init default erase time
    pMD->m_unEraseTime = 700;

    switch ( n_TargetType )
    {
        // case TARGET_PNX5230:
    case TARGET_PNX5230_2A:
        //case TARGET_PNX5230_3A_ROM4:
        //case TARGET_PNX6511_1A_ROM1:

        switch ( n_ConfigId )
        {
        case SCRAM_MEMDEVICE:
            //strcpy(pMD->m_sLocationName , "SCRAM");
            pMD->m_unBaseAddress = 0x1C000000;
            break;

        case USER_MEMDEVICE:
            //  strcpy(pMD->m_sLocationName , "User Defined");
            pMD->m_unBaseAddress = 0x20000000;
            break;

        case DEV0_MEMDEVICE:
            //strcpy(pMD->m_sLocationName , "CS0");
            pMD->m_unBaseAddress = 0x20000000;
            /* erase time for ST512 or Sybley 512 used on sysol5210 */
            pMD->m_unEraseTime = 700;

            break;

        case DEV1_MEMDEVICE:
            // strcpy(pMD->m_sLocationName , "CS1");
            pMD->m_unBaseAddress = 0x30000000;
            break;

        case DEV2_MEMDEVICE:
            //strcpy(pMD->m_sLocationName , "CS2");
            pMD->m_unBaseAddress = 0x40000000;
            break;

        case DEV3_MEMDEVICE:
            // strcpy(pMD->m_sLocationName , "CS3");
            pMD->m_unBaseAddress = 0x44000000;
            break;

        default:
            break;
        }

        break;

    default:
        break;
    }

    pMD->m_nMemoryType = 0;
    memset(pMD->m_sMemoryIdentifier,0x00,MEMORY_IDENTIFIER_LEN);
    pMD->m_unProgTime  = 0;
    // set erase time to 200ms
    //m_unEraseTime = 200;
}

/****************************************************************************
 *
 * Function:     SEQ_ScenarioInit()
 *
 * Description:     Initialize the Target config context
 *
 * Input parameters:   pTC: 
 * 
 *
 * Return:     void
 *
 *****************************************************************************/
static void SEQ_ScenarioInit(void)
{
    //int k;
    Scenario* pScenario=(Scenario* )&(pTargetConfig->m_tScenario);

    // Scenario Config
    //pScenario->m_nCommandType  = BFLOADERAPP_CMD_ERASE | BFLOADERAPP_CMD_WRITE | BFLOADERAPP_CMD_EXEC;
    pScenario->m_nCommandType  =BFLOADERAPP_CMD_ERASE| BFLOADERAPP_CMD_WRITE;// | BFLOADERAPP_CMD_EXEC;
    //    pScenario->m_unJumpDelay    = 0;

    // Erase Config
    if(pSequencerContext->m_bEraseConfig)
    {
        pScenario->m_nCommandType  =BFLOADERAPP_CMD_ERASE| BFLOADERAPP_CMD_WRITE;// | BFLOADERAPP_CMD_EXEC;
        pScenario->m_unJumpDelay    = 0;
    }
    else
    {
        //pScenario->m_tEraseConfig.m_nEraseOption = ERASE_ALL;
        //pScenario->m_tEraseConfig.m_unEraseOffset = 0x00000000;
        // pScenario->m_tEraseConfig.m_unEraseLength = 0x00000000;
        pScenario->m_nCommandType  = BFLOADERAPP_CMD_WRITE;
        pScenario->m_unJumpDelay    = 0;
    }

}

/*****************************************************************************
 *
 * Function:     SEQ_LinkConfigInit()
 *
 * Description:     Default initialization
 *     
 * Input parameters:    n_TargetType    Type of target
 *     n_ConfigId    Configuration Id
 *     pLC     handle to link config 
 * Output parameters:    void
 *
 * Return:     void
 *
 *****************************************************************************/
static BOOL SEQ_LinkConfigInit( int n_TargetType, int n_ConfigId ,LinkConfig* pLC)
{
    if(NULL==pLC)
    {
        return FALSE;
    }

    if(n_TargetType==TARGET_PNX5230_2A)
    {
        switch(n_ConfigId)
        {
        case 	DFLT_BR_COMCONFIG :
            pLC->m_tComConfig.tUartConfig.nBaudRate=COM_BR115200;
            break;

        case USER_BR_COMCONFIG:
            //pLC->m_tComConfig.tUartConfig.nBaudRate=COM_BR230400;
            pLC->m_tComConfig.tUartConfig.nBaudRate=COM_BR921600;//test4;[ 58:58 --> 00:35:   1M37s       ]
            break;

        case DFLT_LD_COMCONFIG:
            pLC->m_tComConfig.tUartConfig.nBaudRate=COM_BR115200;
            break;

        case USER_LD_COMCONFIG:
            // pLC->m_tComConfig.tUartConfig.nBaudRate=COM_BR230400;
            // pLC->m_tComConfig.tUartConfig.nBaudRate=COM_BR460800;
            pLC->m_tComConfig.tUartConfig.nBaudRate=COM_BR921600;//test4;[ 58:58 --> 00:35:   1M37s       ]
            break;

        default:
            pLC->m_tComConfig.tUartConfig.nBaudRate=COM_BR115200;
        }
        pLC->m_tComConfig.tUartConfig.nDataBit  = (int)COM_DATABIT8;
        pLC->m_tComConfig.tUartConfig.nParity   =(int) COM_EVENPARITY;
        pLC->m_tComConfig.tUartConfig.nStopBit  =(int) COM_1STOPBIT;
        pLC->m_tComConfig.tUartConfig.nCtrlFlow = (int)COM_NOCTRLFLOW;

        pLC->m_tComConfig.tUartConfig.nTransfertSize = BFLOADERDLL_UART_NOR_FLASH_TRANSFERT_SIZE;

        return TRUE;
    }
    return FALSE;
}

/****************************************************************************
 *
 * Function:     SEQ_TargetConfigInit()
 *
 * Description:     Initialize the Target config context
 *
 * Input parameters:   n_TargetType Target Type
 *     pTC:  handle to Target configuration
 * 
 *
 * Return:     void
 *
 *****************************************************************************/
static void SEQ_TargetConfigInit(int n_TargetType)
{
    TargetConfig* pTC=pSequencerContext->m_ptTargetConfig;

    // Target Config
    pTC->m_nTargetId  = n_TargetType;

    pTC->m_nCurMemDevice     = DEV0_MEMDEVICE; /*Default setting*/
    //pTC->m_unEBIValue     = 0x50000000;
    //pTC->m_bStopPoint     = FALSE;

    if(!pSequencerContext->m_bLoaderConfig)
    {
#if(0==1)
        pTC->m_nLoaderMemDevice     = DEV1_MEMDEVICE;
#else

        pTC->m_nLoaderMemDevice     = SCRAM_MEMDEVICE;
#endif

        pTC->m_bLoaderIsExternal    = FALSE;
    }

    /*add by h00100243*/
    pTargetConfig->m_nExternalLoaderType= UART_LOADER;

    // Scenario Config
    SEQ_ScenarioInit();

    // Link Config
    SEQ_LinkConfigInit( n_TargetType, DFLT_BR_COMCONFIG ,&pTC->m_atLinkConfig[DFLT_BR_COMCONFIG]);
    SEQ_LinkConfigInit( n_TargetType, DFLT_LD_COMCONFIG ,&pTC->m_atLinkConfig[DFLT_LD_COMCONFIG]);
    SEQ_LinkConfigInit( n_TargetType, USER_BR_COMCONFIG ,&pTC->m_atLinkConfig[USER_BR_COMCONFIG]);
    SEQ_LinkConfigInit( n_TargetType, USER_LD_COMCONFIG ,&pTC->m_atLinkConfig[USER_LD_COMCONFIG]);/*USER_BR_COMCONFIG? Error?*/

    // Memory Config
    SEQ_MemoryConfigInit( n_TargetType, SCRAM_MEMDEVICE , &pTC->m_atMemoryDevice[SCRAM_MEMDEVICE]);
    SEQ_MemoryConfigInit( n_TargetType, USER_MEMDEVICE , &pTC->m_atMemoryDevice[USER_MEMDEVICE]);
    SEQ_MemoryConfigInit( n_TargetType, DEV0_MEMDEVICE , &pTC->m_atMemoryDevice[DEV0_MEMDEVICE]);
    SEQ_MemoryConfigInit( n_TargetType, DEV1_MEMDEVICE , &pTC->m_atMemoryDevice[DEV1_MEMDEVICE]);
    SEQ_MemoryConfigInit( n_TargetType, DEV2_MEMDEVICE , &pTC->m_atMemoryDevice[DEV2_MEMDEVICE]);
    SEQ_MemoryConfigInit( n_TargetType, DEV3_MEMDEVICE , &pTC->m_atMemoryDevice[DEV3_MEMDEVICE]);
    //SEQ_MemoryConfigInit( n_TargetType, NAND_FLASH , &pTC->m_atMemoryDevice[NAND_FLASH]);
    //SEQ_MemoryConfigInit( n_TargetType, SDI , &pTC->m_atMemoryDevice[SDI]);
}

/****************************************************************************
 *
 * Function:     MDM_TargetConfig()
 *
 * Description:    Init  target setting
 *
 * Input parameters:     
 *     targetType     Target type, default: TARGET_PNX5230_2A 
 *     bSecureSupport     Secure support or not
 *     
 *
 * Return:     Error Code
 *
 *****************************************************************************/
unsigned char MDM_TargetConfig(int n_targetType, BOOL b_SecureSupport)
{
    pTargetConfig->m_nTargetId=n_targetType;
    //pTargetConfig->m_bChipsetIsSecure=FALSE;
    pSequencerContext->m_bTargetConfig =TRUE;
    return (unsigned char)ERR_NOERROR;
}


/****************************************************************************
 *
 * Function:     MDM_ComPortInit()
 *
 * Description:    Init  download  setting
 *
 * Input parameters:  
 *     nComPort     Port number 
 *     nBaudRate     Baud rate setting Target type, default:  
 *     nDataBit     Data Bit
 *     nParity     Parity 
 *     nStopBit     Stop Bit
 *
 * Return:     Error Code
 *
 *****************************************************************************/
unsigned char MDM_ComPortConfig(int n_ComPort, int n_BaudRate, int n_DataBit, int n_Parity,int n_StopBit)
{
    //N/A
    pSequencerContext->m_bComPortConfig=TRUE;
    return (unsigned char)ERR_NOERROR;
}

/****************************************************************************
 *
 * Function:     MDM_LoaderConfig()
 *
 * Description:    Init  download  setting
 *
 * Input parameters:
 *     bExternalLoader     External Loader or not
 *     pLoaderData     Data source
 *     loaderLen     Data Length
 *     un_targetMemDev    Target  Memory 
 *
 * Return:     Error Code
 *
 *****************************************************************************/
unsigned char MDM_LoaderConfig( BOOL b_ldExternal,unsigned char* pu_ldData, unsigned int un_ldLen,unsigned int  un_targetMemDev)
{

    pTargetConfig->m_bLoaderIsExternal=b_ldExternal;
    pSequencerContext->m_pucLoaderData=pu_ldData;
    pSequencerContext->m_nLoaderDataLength=(int)un_ldLen;
    pSequencerContext->m_bLoaderConfig=TRUE;

    return (unsigned char)ERR_NOERROR;
}
/****************************************************************************
 *
 * Function:     MDM_EraseConfig()
 *
 * Description:     Set NOR Flash Erase para.
 *
 * Input parameters:  
 *     bErase     Erase or not 
 *     erasOption     ERASE_ALL / ERASE_APPLISIZE / ERASE_CUSTOM
 *     eraseOffset     Erase start address
 *     eraseLen     Erase length
 * 
 *
 * Return:     Error Code
 *
 *****************************************************************************/
unsigned char MDM_EraseConfig (BOOL  b_Erase, unsigned int un_ErasOption, unsigned int un_EraseOffset, unsigned int un_EraseLen)
{
    if(b_Erase)
    {
        pTargetConfig->m_tScenario.m_tEraseConfig.m_nEraseOption=(int)un_ErasOption;
        pTargetConfig->m_tScenario.m_tEraseConfig.m_unEraseOffset=un_EraseOffset;
        pTargetConfig->m_tScenario.m_tEraseConfig.m_unEraseLength=un_EraseLen;
        pSequencerContext->m_bEraseConfig=TRUE;
    }
    else
    {
        pSequencerContext->m_bEraseConfig=FALSE;
    }

    return (unsigned char)ERR_NOERROR;
}


/****************************************************************************
 *
 * Function:     MDM_ImgDownloadInit()
 *
 * Description:    Init  download  , MUST BE CALLED BEFORE ANY OTHER I/F!!
 *
 * Input parameters:  void
 *
 * Return:     void
 *
 *****************************************************************************/
void MDM_ImgDownloadInit(void)
{
    pSequencerContext->m_bLoaderConfig=FALSE;
    pSequencerContext->m_bTargetConfig=FALSE;
    pSequencerContext->m_bEraseConfig=FALSE;
    pSequencerContext->m_bComPortConfig=FALSE;
    pSequencerContext->m_bSibleyFlash = TRUE;

    SEQ_SetSequencerParam(&pSequencerContext->targetConfig);
}


/****************************************************************************
 *
 * Function:     MDM_SEQInit()
 *
 * Description:    Set the target configuration and build the communication with the BR_ROM
 *
 * Input parameters:
 *                       NONE
 *
 *
 * Return:     Error Code
 *
 *****************************************************************************/
unsigned char MDM_SEQInit(unsigned int un_targetMemDev)
{

    int n_targetID = (int)TARGET_PNX5230_2A;

    InitUartIoPort();

    SEQ_TargetConfigInit(n_targetID);

    if (SEQ_InitSeq() != ERR_NOERROR)
    {
        SendDataToPC(APP_ERR_ERROR);
        return (unsigned char )ERR_ERROR;
    }

    pTargetConfig->m_nCurMemDevice = (int)un_targetMemDev;
        
    if(SEQ_MainSeq_ERASE() != ERR_NOERROR)
   	{
		SendDataToPC(APP_ERR_ERROR);
	    return (unsigned char )ERR_ERROR;

	}
	
    return (unsigned char )ERR_NOERROR;
}

/****************************************************************************
 *
 * Function:     MDM_ImgDownload_t()
 *
 * Description:    Init  download  setting
 *
 * Input parameters:  
 *     targetMemDev     target memory device:
 *     SCRAM_MEMDEVICE ,
 *     USER_MEMDEVICE,
 *     DEV0_MEMDEVICE,
 *     DEV1_MEMDEVICE,
 *     DEV2_MEMDEVICE,
 *     DEV3_MEMDEVICE,
 *     
 *     SDI
 *     pSrc     Modem image data source
 *     dataLen     Data length
 *
 * Return:     Error Code
 *
 *****************************************************************************/
unsigned char  MDM_ImgDownload_t(unsigned char* pun_Src, unsigned int un_DataLen, LPRECT pstRect)
{
	memcpy(&g_stRect, pstRect, sizeof(g_stRect));
	
	g_dwSdUpdateFlag = TRUE;
	
	return MDM_ImgDownload(pun_Src, un_DataLen);
}


/****************************************************************************
 *
 * Function:     MDM_ImgDownload()
 *
 * Description:    Init  download  setting
 *
 * Input parameters:  
 *     targetMemDev     target memory device:
 *     SCRAM_MEMDEVICE ,
 *     USER_MEMDEVICE,
 *     DEV0_MEMDEVICE,
 *     DEV1_MEMDEVICE,
 *     DEV2_MEMDEVICE,
 *     DEV3_MEMDEVICE,
 *     
 *     SDI
 *     pSrc     Modem image data source
 *     dataLen     Data length
 *
 * Return:     Error Code
 *
 *****************************************************************************/
unsigned char  MDM_ImgDownload(unsigned char* pun_Src, unsigned int un_DataLen)
{

	if(pun_Src==NULL||un_DataLen==0)
    {
#if defined (WM_DEBUG_EN)
	   DEBUGMSG(1,(TEXT("Error : Invalid pun_Src or  un_DataLen \r\n")));
#endif
  	   SendDataToPC(APP_ERR_ERROR);
    
	   return (unsigned char )ERR_ERROR;
    }
	   
    pSequencerContext->m_pucAppliData=pun_Src;
    pSequencerContext->m_nAppliDataLength=(int)un_DataLen;

    if(SEQ_MainSeq_BH()!=ERR_NOERROR)
    {
        SendDataToPC(APP_ERR_ERROR);
        return (unsigned char )ERR_ERROR;
    }

    BFLOADER_ComCloseDialog(NULL);

    return (unsigned char )ERR_NOERROR;
}

